package com.william.jdbcplus.core.condition.lambda;


import com.william.jdbcplus.core.toolkit.lambda.support.SFunction;

import java.io.Serializable;

/**
 * Select 片段
 *
 * @author niliwei
 */
public interface Select<Wrap> extends Serializable {
    /**
     * select 脚本
     *
     * @param sql
     * @return
     */
    <R> Wrap select(String sql);

    /**
     * 选取字段
     *
     * @param column
     * @return
     */
    <R> Wrap select(SFunction<R, ?> column);

    /**
     * select column1, column2, ...
     *
     * @param columns
     * @return
     */
    <R> Wrap select(SFunction<R, ?>... columns);

    /**
     * select column as column
     *
     * @param column
     * @param asColumn
     * @return
     */
    <R, R2> Wrap selectAs(SFunction<R, ?> column, SFunction<R2, ?> asColumn);

    /**
     * 自定义select Max
     * <p>
     * 例: selectMax("id")
     * 等价于 select max(id)
     * </p>
     *
     * @param column
     * @return
     */
    <R> Wrap selectMax(SFunction<R, ?> column);

    /**
     * 自定义selectMaxAs
     * <p>
     * 例: selectMaxAs("id", "maxId")
     * 等价于 select max(id) as maxId
     * </p>
     *
     * @param column
     * @param asColumn
     * @param <R>
     * @param <R2>
     * @return
     */
    <R, R2> Wrap selectMaxAs(SFunction<R, ?> column, SFunction<R2, ?> asColumn);

    /**
     * 自定义select Min
     * <p>
     * 例: selectMin("id")
     * 等价于 select min(id)
     * </p>
     *
     * @param column
     * @return
     */
    <R> Wrap selectMin(SFunction<R, ?> column);

    /**
     * 自定义selectMinAs
     * <p>
     * 例: selectMinAs("id", "minId")
     * 等价于 select min(id) as minId
     * </p>
     *
     * @param column
     * @param asColumn
     * @param <R>
     * @param <R2>
     * @return
     */
    <R, R2> Wrap selectMinAs(SFunction<R, ?> column, SFunction<R2, ?> asColumn);

    /**
     * 自定义select
     * <p>
     * 例: selectSum("id")
     * 等价于 select sum(id)
     * </p>
     *
     * @param column
     * @return
     */
    <R> Wrap selectSum(SFunction<R, ?> column);

    /**
     * 自定义 selectSumAs
     * <p>
     * 例: selectSumAs("id", "sumId")
     * 等价于 select sum(id) as sumId
     * </p>
     *
     * @param column
     * @param asColumn
     * @param <R>
     * @param <R2>
     * @return
     */
    <R, R2> Wrap selectSumAs(SFunction<R, ?> column, SFunction<R2, ?> asColumn);

    /**
     * 自定义select
     * <p>
     * 例: selectAvg("id")
     * 等价于 select avg(id)
     * </p>
     *
     * @param column
     * @return
     */
    <R> Wrap selectAvg(SFunction<R, ?> column);

    /**
     * 自定义 selectAvgAs
     * <p>
     * 例: selectAvgAs("id", "avgId")
     * 等价于 select avg(id) as avgId
     * </p>
     *
     * @param column
     * @param asColumn
     * @param <R>
     * @param <R2>
     * @return
     */
    <R, R2> Wrap selectAvgAs(SFunction<R, ?> column, SFunction<R2, ?> asColumn);

    /**
     * 自定义select
     * <p>
     * 例: selectCount("id")
     * 等价于 select count(id)
     * </p>
     *
     * @param column
     * @return
     */
    <R> Wrap selectCount(SFunction<R, ?> column);

    /**
     * 自定义 selectCountAs
     * <p>
     * 例: selectCountAs("id", "countId")
     * 等价于 select count(id) as countId
     * </p>
     *
     * @param column
     * @param asColumn
     * @param <R>
     * @param <R2>
     * @return
     */
    <R, R2> Wrap selectCountAs(SFunction<R, ?> column, SFunction<R2, ?> asColumn);


    /**
     * 选取类的所有字段
     *
     * @param clazz
     * @return
     */
    Wrap selectAll(Class<?> clazz);

    /**
     * 是否带 Distinct 查询
     *
     * @param isDistinct
     * @return
     */
    Wrap selectDistinct(boolean isDistinct);

}
